home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / mipmap_lines.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.3 KB  |  302 lines

  1.  
  2. /* mipmap_lines.c - by David Blythe, SGI */
  3.  
  4. /* Different mipmap filters. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <GL/glut.h>
  10. #include "texture.h"
  11. #include "izoom.h"
  12.  
  13. static int w = 1024, h = 512;
  14.  
  15. void 
  16. reshape(int w, int h)
  17. {
  18.   glViewport(0, 0, w, h);
  19.   glMatrixMode(GL_PROJECTION);
  20.   glLoadIdentity();
  21.   gluPerspective(40.0, (GLfloat) w / (GLfloat) h, 1.0, 20.0);
  22.  
  23.   gluLookAt(0, 1, 3,
  24.     0, 0, 0,
  25.     0, 1, 0);
  26.   glMatrixMode(GL_MODELVIEW);
  27.   glLoadIdentity();
  28. }
  29.  
  30. int original_width, reduced_width, global_comp;
  31. unsigned *original, *reduced;
  32.  
  33. void 
  34. getimgrow(short *buf, int y)
  35. {
  36.   int i;
  37.   unsigned *p = &original[y * original_width];
  38.   int shift = global_comp * 8;
  39.   unsigned int mask = 0xff << shift;
  40.  
  41.   for (i = 0; i < original_width; i++) {
  42.     buf[i] = (p[i] & mask) >> shift;
  43.   }
  44. }
  45.  
  46. void 
  47. putimgrow(short *buf, int y)
  48. {
  49.   int i;
  50.   unsigned *p = &reduced[y * reduced_width];
  51.   int shift = global_comp * 8;
  52.   unsigned int mask = 0xff << shift;
  53.  
  54.   for (i = 0; i < reduced_width; i++) {
  55.     p[i] = (p[i] & ~mask) | (buf[i] << shift);
  56.   }
  57. }
  58.  
  59. void 
  60. buildMitchellMipmaps(int components, int width, int height, unsigned
  61.   *buf)
  62. {
  63.   int level = 0;
  64.  
  65.   original_width = width;
  66.   original = buf;
  67.   glTexImage2D(GL_TEXTURE_2D, level, components, width,
  68.     height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  69.     original);
  70.   while (width) {
  71.     reduced_width = width / 2;
  72.     for (global_comp = 0; global_comp < 4; global_comp++) {
  73.       filterzoom(getimgrow, putimgrow, width, height, width / 2,
  74.         height / 2, MITCHELL, 1.);
  75.     }
  76.     glTexImage2D(GL_TEXTURE_2D, ++level, components, width / 2,
  77.       height / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  78.       reduced);
  79.     width /= 2, height /= 2;
  80.     memcpy(original, reduced, width * height * sizeof(unsigned));
  81.     original_width = width;
  82.     printf("build level %d\n", level);
  83.   }
  84. }
  85.  
  86. int width = 256, height = 256;
  87. int grid_space = 4;
  88.  
  89. void 
  90. init_textures(char *filename)
  91. {
  92.   unsigned *buf;
  93.   int components;
  94.  
  95.   if (filename) {
  96.     buf = read_texture(filename, &width, &height, &components);
  97.     if (buf == NULL) {
  98.       fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  99.         filename);
  100.       exit(1);
  101.     } else {
  102.       printf("%d x %d texture loaded\n", width, height);
  103.     }
  104.   } else {
  105.     int i, j;
  106.     components = 4;
  107.     buf = (unsigned *) malloc(width * height * sizeof(unsigned));
  108.     for (i = 0; i < height; i++)
  109.       for (j = 0; j < width; j++)
  110.         if ((i % grid_space) && (j % grid_space))
  111.           buf[i * width + j] = 0xffffffff;
  112.         else
  113.           buf[i * width + j] = 0;
  114.   }
  115.  
  116. #ifdef GL_EXT_texture_object
  117.   glBindTextureEXT(GL_TEXTURE_2D, 1);
  118. #else
  119.   glNewList(1001, GL_COMPILE);
  120. #endif
  121.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  122.  
  123.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  124.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  125.     GL_LINEAR_MIPMAP_LINEAR);
  126.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  127.   gluBuild2DMipmaps(GL_TEXTURE_2D, components, width, height, GL_RGBA,
  128.     GL_UNSIGNED_BYTE, buf);
  129. #ifndef GL_EXT_texture_object
  130.   glEndList();
  131. #endif
  132.  
  133. #ifdef GL_EXT_texture_object
  134.   glBindTextureEXT(GL_TEXTURE_2D, 2);
  135. #else
  136.   glNewList(1002, GL_COMPILE);
  137. #endif
  138.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  139.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  140.   reduced = (unsigned *) malloc(width * height * sizeof(unsigned));
  141.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  142.     GL_LINEAR_MIPMAP_LINEAR);
  143.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  144.   buildMitchellMipmaps(components, width, height, buf);
  145. #ifndef GL_EXT_texture_object
  146.   glEndList();
  147. #endif
  148.  
  149.   free(buf);
  150.   free(reduced);
  151. }
  152.  
  153. void 
  154. init(char *filename)
  155. {
  156.   glEnable(GL_TEXTURE_2D);
  157.   init_textures(filename);
  158.   glNewList(1, GL_COMPILE);
  159.   glColor3f(1., 1., 1.);
  160.   glBegin(GL_QUADS);
  161.   glTexCoord2f(0, 1);
  162.   glVertex3f(-4, 0, -10);
  163.   glTexCoord2f(1, 1);
  164.   glVertex3f(4, 0, -10);
  165.   glTexCoord2f(1, 0);
  166.   glVertex3f(4, 0, 3);
  167.   glTexCoord2f(0, 0);
  168.   glVertex3f(-4, 0, 3);
  169.   glEnd();
  170.   glEndList();
  171.   glClearColor(.2, 0, .9, 0);
  172. }
  173.  
  174. void 
  175. display(void)
  176. {
  177.   glClear(GL_COLOR_BUFFER_BIT);
  178.  
  179.   glViewport(0, 0, w / 2, h);
  180. #ifdef GL_EXT_texture_object
  181.   glBindTextureEXT(GL_TEXTURE_2D, 1);
  182. #else
  183.   glCallList(1001);
  184. #endif
  185.   glCallList(1);
  186.  
  187.   glViewport(w / 2, 0, w / 2, h);
  188. #ifdef GL_EXT_texture_object
  189.   glBindTextureEXT(GL_TEXTURE_2D, 2);
  190. #else
  191.   glCallList(1002);
  192. #endif
  193.   glCallList(1);
  194.   glutSwapBuffers();
  195. }
  196.  
  197. void 
  198. idle(void)
  199. {
  200.   glRotatef(.1, 1, 0, 0);
  201.   glutPostRedisplay();
  202. }
  203.  
  204. void 
  205. bidle(void)
  206. {
  207.   glRotatef(-.1, 1, 0, 0);
  208.   glutPostRedisplay();
  209. }
  210.  
  211. /* ARGSUSED1 */
  212. void
  213. mouse(int button, int state, int x, int y)
  214. {
  215.   if (state == GLUT_DOWN) {
  216.     switch (button) {
  217.     case GLUT_LEFT_BUTTON:
  218.       glutIdleFunc(idle);
  219.       break;
  220.     case GLUT_MIDDLE_BUTTON:
  221.       glutIdleFunc(bidle);
  222.       break;
  223.     case GLUT_RIGHT_BUTTON:
  224.       break;
  225.     }
  226.   } else {
  227.     glutIdleFunc(NULL);
  228.   }
  229. }
  230.  
  231. void 
  232. help(void)
  233. {
  234.   printf("'h'   - help\n");
  235.   printf("'g'   - increase line spacing\n");
  236.   printf("'G'   - decrease line spacing\n");
  237.   printf("'s'   - double texture dimensions\n");
  238.   printf("'S'   - halve texture dimensions\n");
  239. }
  240.  
  241. char *filename;
  242.  
  243. /* ARGSUSED1 */
  244. void
  245. key(unsigned char key, int x, int y)
  246. {
  247.   switch (key) {
  248.   case 'h':
  249.     help();
  250.     break;
  251.   case 'g':
  252.     grid_space++;
  253.     init_textures(filename);
  254.     printf("grid spacing %d\n", grid_space);
  255.     break;
  256.   case 'G':
  257.     grid_space--;
  258.     if (grid_space <= 0)
  259.       grid_space = 1;
  260.     init_textures(filename);
  261.     printf("grid spacing %d\n", grid_space);
  262.     break;
  263.   case 's':
  264.     height = width *= 2;
  265.     if (height > 1024)
  266.       height = width = 1024;
  267.     init_textures(filename);
  268.     printf("texture size %d\n", height);
  269.     break;
  270.   case 'S':
  271.     height = width /= 2;
  272.     init_textures(filename);
  273.     printf("texture size %d\n", height);
  274.     break;
  275.   default:
  276.     return;
  277.   case '\033':
  278.     exit(0);
  279.     break;
  280.   }
  281.   glutPostRedisplay();
  282. }
  283.  
  284. int 
  285. main(int argc, char *argv[])
  286. {
  287.   glutInit(&argc, argv);
  288.   glutInitWindowSize(w, h);
  289.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  290.   (void) glutCreateWindow("Left: GLU mipmaps, Right: Mitchell mipmaps");
  291.   if (argc > 1)
  292.     init(filename = argv[1]);
  293.   else
  294.     init(filename = 0);
  295.   glutDisplayFunc(display);
  296.   glutKeyboardFunc(key);
  297.   glutReshapeFunc(reshape);
  298.   glutMouseFunc(mouse);
  299.   glutMainLoop();
  300.   return 0;             /* ANSI C requires main to return int. */
  301. }
  302.